home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / bash_114.zip / bash-1.14.2 / builtins / kill.def < prev    next >
Encoding:
Text File  |  1994-04-14  |  6.7 KB  |  281 lines

  1. This file is kill.def, from which is created kill.c.
  2. It implements the builtin "kill" in Bash.
  3.  
  4. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. $PRODUCES kill.c
  23.  
  24. $BUILTIN kill
  25. $FUNCTION kill_builtin
  26. $DEPENDS_ON JOB_CONTROL
  27. $SHORT_DOC kill [-s sigspec | -sigspec] [pid | job]... | -l [signum]
  28. Send the processes named by PID (or JOB) the signal SIGSPEC.  If
  29. SIGSPEC is not present, then SIGTERM is assumed.  An argument of `-l'
  30. lists the signal names; if arguments follow `-l' they are assumed to
  31. be signal numbers for which names should be listed.  Kill is a shell
  32. builtin for two reasons: it allows job IDs to be used instead of
  33. process IDs, and, if you have reached the limit on processes that
  34. you can create, you don't have to start a process to kill another one.
  35. $END
  36.  
  37. /* Not all systems declare ERRNO in errno.h... and some systems #define it! */
  38. #if !defined (errno)
  39. extern int errno;
  40. #endif /* !errno */
  41.  
  42. #include "../shell.h"
  43. #include "../trap.h"
  44. #include "../jobs.h"
  45. #include "common.h"
  46. #include <errno.h>
  47.  
  48. #if defined (JOB_CONTROL)
  49. extern int interactive;
  50. extern int posixly_correct;
  51.  
  52. #if !defined (CONTINUE_AFTER_KILL_ERROR)
  53. #  define CONTINUE_OR_FAIL return (EXECUTION_FAILURE)
  54. #else
  55. #  define CONTINUE_OR_FAIL goto continue_killing
  56. #endif /* CONTINUE_AFTER_KILL_ERROR */
  57.  
  58. /* Here is the kill builtin.  We only have it so that people can type
  59.    kill -KILL %1?  No, if you fill up the process table this way you
  60.    can still kill some. */
  61. int
  62. kill_builtin (list)
  63.      WORD_LIST *list;
  64. {
  65.   int signal = SIGTERM;
  66.   int any_succeeded = 0, listing = 0, saw_signal = 0;
  67.   char *sigspec = "TERM", *word;
  68.   pid_t pid;
  69.  
  70.   if (!list)
  71.     return (EXECUTION_SUCCESS);
  72.  
  73.   /* Process options. */
  74.   while (list)
  75.     {
  76.       word = list->word->word;
  77.  
  78.       if (ISOPTION (word, 'l'))
  79.     {
  80.       listing++;
  81.       list = list->next;
  82.     }
  83.       else if (ISOPTION (word, 's'))
  84.     {
  85.       list = list->next;
  86.       if (list)
  87.         {
  88.           sigspec = list->word->word;
  89.           if (sigspec[0] == '0' && !sigspec[1])
  90.         signal = 0;
  91.           else
  92.         signal = decode_signal (sigspec);
  93.           list = list->next;
  94.         }
  95.       else
  96.         {
  97.           builtin_error ("-s requires an argument");
  98.           return (EXECUTION_FAILURE);
  99.         }
  100.     }
  101.       else if (ISOPTION (word, '-'))
  102.     {
  103.       list = list->next;
  104.       break;
  105.     }
  106.       /* If this is a signal specification then process it.  We only process
  107.      the first one seen; other arguments may signify process groups (e.g,
  108.      -num == process group num). */
  109.       else if ((*word == '-') && !saw_signal)
  110.     {
  111.       sigspec = word + 1;
  112.       signal = decode_signal (sigspec);
  113.       saw_signal++;
  114.       list = list->next;
  115.     }
  116.       else
  117.     break;
  118.     }
  119.  
  120.   if (listing)
  121.     {
  122.       if (!list)
  123.     {
  124.       register int i;
  125.       register int column = 0;
  126.       char *name;
  127.  
  128.       for (i = 1; i < NSIG; i++)
  129.         {
  130.           name = signal_name (i);
  131.           if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
  132.         continue;
  133.  
  134.           if (posixly_correct)
  135.             printf ("%s%s", name, (i == NSIG - 1) ? "" : " ");
  136.           else
  137.         {
  138.           printf ("%2d) %s", i, name);
  139.  
  140.           if (++column < 4)
  141.             printf ("\t");
  142.           else
  143.             {
  144.               printf ("\n");
  145.               column = 0;
  146.             }
  147.         }
  148.         }
  149.  
  150.       if (posixly_correct || column != 0)
  151.         printf ("\n");
  152.     }
  153.       else
  154.     {
  155.       /* List individual signal names. */
  156.       while (list)
  157.         {
  158.           int signum;
  159.           char *name;
  160.  
  161.           if ((sscanf (list->word->word, "%d", &signum) != 1) ||
  162.           (signum <= 0))
  163.         {
  164.         list_error:
  165.           builtin_error ("bad signal number: %s", list->word->word);
  166.           list = list->next;
  167.           continue;
  168.         }
  169.  
  170.           /* This is specified by Posix.2 so that exit statuses can be
  171.          mapped into signal numbers. */
  172.           if (signum > 128)
  173.         signum -= 128;
  174.  
  175.           if (signum >= NSIG)
  176.         goto list_error;
  177.  
  178.           name = signal_name (signum);
  179.           if (STREQN (name, "SIGJUNK", 7) || STREQN (name, "Unknown", 7))
  180.         {
  181.           list = list->next;
  182.           continue;
  183.         }
  184.           printf ("%s\n", name);
  185.           list = list->next;
  186.         }
  187.     }
  188.       return (EXECUTION_SUCCESS);
  189.     }
  190.  
  191.   /* OK, we are killing processes. */
  192.   if (signal == NO_SIG)
  193.     {
  194.       builtin_error ("bad signal spec `%s'", sigspec);
  195.       return (EXECUTION_FAILURE);
  196.     }
  197.  
  198.   while (list)
  199.     {
  200.       word = list->word->word;
  201.  
  202.       if (*word == '-')
  203.     word++;
  204.  
  205.       if (all_digits (word))
  206.     {
  207.       /* Use the entire argument in case of minus sign presence. */
  208.       pid = (pid_t) atoi (list->word->word);
  209.  
  210.       if (kill_pid (pid, signal, 0) < 0)
  211.         goto signal_error;
  212.       else
  213.         any_succeeded++;
  214.     }
  215.       else if (*list->word->word != '%')
  216.     {
  217.       builtin_error ("No such pid %s", list->word->word);
  218.       CONTINUE_OR_FAIL;
  219.     }
  220. #if 1
  221.       else if (interactive)
  222.     /* Posix.2 says you can kill without job control active (4.32.4) */
  223. #else
  224.       else if (job_control)    /* can't kill jobs if not using job control */
  225. #endif
  226.     {            /* Must be a job spec.  Check it out. */
  227.       int job;
  228.       sigset_t set, oset;
  229.  
  230.       BLOCK_CHILD (set, oset);
  231.       job = get_job_spec (list);
  232.  
  233.       if (job < 0 || job >= job_slots || !jobs[job])
  234.         {
  235.           if (job != DUP_JOB)
  236.         builtin_error ("No such job %s", list->word->word);
  237.           UNBLOCK_CHILD (oset);
  238.           CONTINUE_OR_FAIL;
  239.         }
  240.  
  241.       /* Job spec used.  Kill the process group. If the job was started
  242.          without job control, then its pgrp == shell_pgrp, so we have
  243.          to be careful.  We take the pid of the first job in the pipeline
  244.          in that case. */
  245.       if (jobs[job]->flags & J_JOBCONTROL)
  246.         pid = jobs[job]->pgrp;
  247.       else
  248.         pid = jobs[job]->pipe->pid;
  249.  
  250.       UNBLOCK_CHILD (oset);
  251.  
  252.       if (kill_pid (pid, signal, 1) < 0)
  253.         {
  254.         signal_error:
  255.           if (errno == EPERM)
  256.         builtin_error ("(%d) - Not owner", (int)pid);
  257.           else if (errno == ESRCH)
  258.         builtin_error ("(%d) - No such pid", (int)pid);
  259.           else
  260.         builtin_error ("Invalid signal %d", signal);
  261.           CONTINUE_OR_FAIL;
  262.         }
  263.       else
  264.         any_succeeded++;
  265.     }
  266.       else
  267.     {
  268.       builtin_error ("bad process specification `%s'", list->word->word);
  269.       CONTINUE_OR_FAIL;
  270.     }
  271.     continue_killing:
  272.       list = list->next;
  273.     }
  274.  
  275.   if (any_succeeded)
  276.     return (EXECUTION_SUCCESS);
  277.   else
  278.     return (EXECUTION_FAILURE);
  279. }
  280. #endif /* JOB_CONTROL */
  281.